/* **********************************************************************
版本: 2022.3.62f1
作者: wzz
日期: 2025-8-7
描述: 原始 c# tcp
***********************************************************************/

using System;
using System.Net;
using System.Net.Sockets;
using static FixDataAdpter;
using TcpClient = System.Net.Sockets.TcpClient;

namespace Framework
{
    public class NetTcpClient : IBaseNet
    {
        private TcpClient mTcpClient;

        /// <summary>
        /// 正在连接的Ip, 空为没有连接
        /// </summary>
        public string Ip
        {
            get
            {
                return mIp;
            }
        }

        /// <summary>
        /// 正在连接的Port, 空为没有连接
        /// </summary>
        public int Port
        {
            get
            {
                return mPort;
            }
        }

        private NetMgr mNetMgr;
        private FixDataAdpter mFixDataAdpter;
        private string mIp = string.Empty;
        private int mPort = 0;

        public NetTcpClient(NetMgr netMgr, FixDataAdpter fixDataAdpter)
        {
            mNetMgr = netMgr;
            mFixDataAdpter = fixDataAdpter;

            mFixDataAdpter.OnParseSuccessCallback = delegate (byte[] data)
            {
                mNetMgr.PupReceiveMsgBytes(data);
            };
        }

        public void ConnectAsync(string ip, int port)
        {
            try
            {
                if (mTcpClient != null)
                {
                    if (mTcpClient.Connected)
                    {
                        Log($"已连接：{Ip}:{Port}");
                        return;
                    }
                    Log($"正在连接中：{Ip}:{Port}");
                    return;
                }

                mIp = ip;
                mPort = port;

                IPAddress iPAddress = IPAddress.Parse(ip);
                var family = iPAddress.AddressFamily == AddressFamily.InterNetworkV6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork;
                mTcpClient = new TcpClient(family);
                mTcpClient.NoDelay = true;
                mTcpClient.ReceiveTimeout = 0;
                mTcpClient.SendTimeout = 0;
                mTcpClient.BeginConnect(ip, port, new AsyncCallback(OnConnect), null);
            }
            catch (Exception e)
            {
                var msg = $"启动连接失败:{CheckMessage(e.Message)}";
                LogWarning(msg);
                mNetMgr.Destroy();
                mNetMgr.PupNetEvent(NetMgr.ENetCode.ConnectError, msg);
            }
        }

        /// <summary>
        /// 连接回调
        /// </summary>
        private void OnConnect(IAsyncResult asyncResult)
        {
            if (mTcpClient == null)
                return;
            try
            {
                // 如果连接失败，EndConnect方法会抛出一个SocketException异常
                mTcpClient.EndConnect(asyncResult);

                Log($"连接成功：{Ip}:{Port}");
                mNetMgr.PupNetEvent(NetMgr.ENetCode.Connected, string.Empty);

                mFixDataAdpter.ReSet();
                // 连接成功，监听数据
                mTcpClient.GetStream().BeginRead(mFixDataAdpter.Buffer, 0, mFixDataAdpter.Buffer.Length, new AsyncCallback(OnRead), null);
            }
            catch (Exception e)
            {
                var msg = $"连接失败:{CheckMessage(e.Message)}";
                LogWarning(msg);
                mNetMgr.Destroy();
                mNetMgr.PupNetEvent(NetMgr.ENetCode.ConnectError, msg);
            }
        }

        /// <summary>
        /// 监听接收信息
        /// </summary>
        private void OnRead(IAsyncResult asyncResult)
        {
            try
            {
                if (mTcpClient == null)
                    return;

                int bytesRead = 0;
                NetworkStream stream = mTcpClient.GetStream();
                lock (stream)
                {
                    // 此处连接断开抛出会异常
                    bytesRead = stream.EndRead(asyncResult);
                }
                if (bytesRead < 1)
                {   // 未读取到数据
                    return;
                }

                // 分析数据包内容，抛给逻辑层
                mFixDataAdpter.SplitPackage(bytesRead);

                lock (stream)
                {
                    //分析完，再次监听服务器发过来的新消息
                    mFixDataAdpter.ClearBuffer();
                    stream.BeginRead(mFixDataAdpter.Buffer, 0, mFixDataAdpter.Buffer.Length, new AsyncCallback(OnRead), null);
                }
            }
            catch (HeadFlagLargeException e)
            {
                LogWarning(e.Message);
                mFixDataAdpter.ReSet();
                mTcpClient.GetStream().BeginRead(mFixDataAdpter.Buffer, 0, mFixDataAdpter.Buffer.Length, new AsyncCallback(OnRead), null);
            }
            catch (Exception e)
            {
                var msg = $"断开连接：{CheckMessage(e.Message)}";
                LogWarning(msg);

                mNetMgr.Destroy();
                mNetMgr.PupNetEvent(NetMgr.ENetCode.Disconnect, msg);
            }
        }

        public void SendMsg(byte[] data)
        {
            if (mTcpClient == null)
            {
                Log("未启动");
                return;
            }

            if (!mTcpClient.Connected)
            {
                LogWarning("未连接成功");
                return;
            }
            var newData = mFixDataAdpter.WriteHeaderInBytes(data);
            mTcpClient.GetStream().BeginWrite(newData, 0, newData.Length, new AsyncCallback(OnWrite), null);
        }

        /// <summary>
        /// 发送写入回调
        /// </summary>
        private void OnWrite(IAsyncResult asyncResult)
        {
            if (mTcpClient == null)
            {
                return;
            }

            try
            {
                mTcpClient.GetStream().EndWrite(asyncResult);
            }
            catch (Exception e)
            {
                var msg = $"断开连接：{CheckMessage(e.Message)}";
                LogWarning(msg);

                mNetMgr.Destroy();
                mNetMgr.PupNetEvent(NetMgr.ENetCode.Disconnect, msg);
            }
        }

        /// <summary>
        /// try catch 捕获的信息，可能因为编码原因，带有大量空格
        /// </summary>
        private string CheckMessage(string message)
        {
            return message.Replace("\0", "").Replace("\r\n", "");
        }

        /// <summary>
        /// 普通信息
        /// </summary>
        public void Log(string log)
        {
            LogPro.DebugPro.Log(log, LogPro.LogColor.Green);
        }

        /// <summary>
        /// 警告信息
        /// </summary>
        public void LogWarning(string log)
        {
            LogPro.DebugPro.LogWarning(log);
        }

        public void Close()
        {
            if (mTcpClient == null)
                return;
            mTcpClient.Dispose();
            mTcpClient = null;
        }

        public void Destroy()
        {
            if (mTcpClient == null)
                return;

            mTcpClient.Dispose();
            mTcpClient = null;
        }
    }
}